﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RayDen.Library.Core;
using RayDen.RayEngine.Corrector.Types;

namespace RayDen.RayEngine.Corrector.Samplers
{
    public interface IImagePlaneSampler
    {
        ImagePlaneSample GetSample(int index);
    }

    public abstract class ImagePlaneSampler : IImagePlaneSampler
    {
        public int Width, Height;
        public IRandomProvider randomProvider;

        protected ImagePlaneSampler(IRandomProvider p)
        {
            randomProvider = p;
        }
        public abstract ImagePlaneSample GetSample(int index);
    }


    public class UniformImagePlaneSampler : ImagePlaneSampler
    {
        protected readonly Tuple<int, int>[] sampleIndex;
        public UniformImagePlaneSampler(int w, int h)
            : base(null)
        {
            this.Width = w;
            this.Height = h;
            this.randomProvider = new FastRandom();
            sampleIndex = new Tuple<int, int>[w * h];
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    sampleIndex[j + i * w] = new Tuple<int, int>(j, i);
                }
            }
        }

        public override ImagePlaneSample GetSample(int index)
        {
            var sample = new ImagePlaneSample
            {
                X = sampleIndex[index].Item1,
                Y = sampleIndex[index].Item2,
                Time = 0.5f,
                U = (float) Width/sampleIndex[index].Item1,
                V = (float) Height/sampleIndex[index].Item2
            };
            return sample;
        }
    }


    public class RandomImagePlaneSampler : ImagePlaneSampler
    {
        public RandomImagePlaneSampler(int w, int h)
            : base(new FastRandom())
        {
            this.Width = w;
            this.Height = h;
        }

        public override ImagePlaneSample GetSample(int index)
        {
            var sample = new ImagePlaneSample
            {
                X = Width * (1f - 2f * randomProvider.NextFloat()) + 0.5f,
                Y = Height * (1f - 2f * randomProvider.NextFloat()) + 0.5f,
                Time = randomProvider.NextFloat(),
                U = randomProvider.NextFloat(),
                V = randomProvider.NextFloat()
            };
            return sample;
        }
    }


}
